{% extends "base.html" %}

{% block title %}文档切片 - MinerU 文档解析系统{% endblock %}

{% block page_title %}文档切片{% endblock %}

{% block content %}
<div class="fade-in">
    <!-- 切片配置 -->
    <div class="bg-white rounded-xl shadow-sm p-6 mb-6">
        <h3 class="text-lg font-semibold text-gray-800 mb-4">切片配置</h3>
        
        <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
            <div>
                <label class="block text-sm font-medium text-gray-700 mb-2">切片策略</label>
                <select id="sliceStrategy" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
                    <option value="semantic">语义切片</option>
                    <option value="paragraph">段落切片</option>
                    <option value="fixed">固定大小切片</option>
                </select>
            </div>
            
            <div>
                <label class="block text-sm font-medium text-gray-700 mb-2">切片大小</label>
                <input type="number" id="chunkSize" value="1000" min="100" max="5000" 
                       class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
                <p class="text-xs text-gray-500 mt-1">字符数（仅固定大小模式）</p>
            </div>
            
            <div>
                <label class="block text-sm font-medium text-gray-700 mb-2">重叠大小</label>
                <input type="number" id="overlapSize" value="200" min="0" max="1000" 
                       class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
                <p class="text-xs text-gray-500 mt-1">字符数</p>
            </div>
            
            <div>
                <label class="block text-sm font-medium text-gray-700 mb-2">选择解析任务</label>
                <select id="parseTaskSelect" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
                    <option value="">请选择已完成的解析任务</option>
                </select>
            </div>
        </div>
        
        <div class="mt-6 flex justify-end">
            <button id="startSlicingBtn" class="btn-primary text-white px-6 py-2 rounded-md hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed" disabled>
                <i class="fas fa-cut mr-2"></i>开始切片
            </button>
        </div>
    </div>
    
    <!-- 切片任务列表 -->
    <div class="bg-white rounded-xl shadow-sm p-6 mb-6">
        <div class="flex items-center justify-between mb-4">
            <h3 class="text-lg font-semibold text-gray-800">切片任务</h3>
            <button id="refreshSlicingBtn" class="text-blue-600 hover:text-blue-800">
                <i class="fas fa-sync-alt"></i>
            </button>
        </div>
        
        <div id="slicingTasksList" class="space-y-4">
            <div class="text-center py-8 text-gray-500">
                <i class="fas fa-spinner fa-spin text-2xl mb-2"></i>
                <p>加载中...</p>
            </div>
        </div>
    </div>
    
    <!-- 切片结果预览 -->
    <div class="bg-white rounded-xl shadow-sm p-6">
        <h3 class="text-lg font-semibold text-gray-800 mb-4">切片结果预览</h3>
        
        <div id="slicePreview" class="space-y-4">
            <div class="text-center py-8 text-gray-500">
                <i class="fas fa-eye-slash text-2xl mb-2"></i>
                <p>选择一个切片任务查看结果</p>
            </div>
        </div>
    </div>
</div>

<!-- 切片详情模态框 -->
<div id="sliceModal" class="modal fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full hidden">
    <div class="relative top-20 mx-auto p-5 border w-11/12 max-w-4xl shadow-lg rounded-md bg-white">
        <div class="mt-3">
            <div class="flex items-center justify-between mb-4">
                <h3 class="text-lg font-semibold text-gray-800">切片详情</h3>
                <button onclick="closeSliceModal()" class="text-gray-400 hover:text-gray-600">
                    <i class="fas fa-times"></i>
                </button>
            </div>
            
            <div id="sliceDetails" class="space-y-4">
                <!-- 切片详情将通过JavaScript动态生成 -->
            </div>
        </div>
    </div>
</div>
{% endblock %}

{% block extra_js %}
<script>
let currentSliceTask = null;

// 页面加载时初始化
document.addEventListener('DOMContentLoaded', function() {
    loadParseTasks();
    loadSlicingTasks();
    setupEventListeners();
});

// 设置事件监听器
function setupEventListeners() {
    document.getElementById('refreshSlicingBtn').addEventListener('click', loadSlicingTasks);
    document.getElementById('startSlicingBtn').addEventListener('click', startSlicing);
    document.getElementById('sliceStrategy').addEventListener('change', updateChunkSizeVisibility);
}

// 加载解析任务列表
async function loadParseTasks() {
    try {
        const response = await apiRequest('/api/v1/tasks/my-tasks?status=completed');
        const select = document.getElementById('parseTaskSelect');
        
        if (response.items && response.items.length > 0) {
            select.innerHTML = `
                <option value="">请选择已完成的解析任务</option>
                ${response.items.map(task => `
                    <option value="${task.task_id}">${task.filename} (${task.task_id})</option>
                `).join('')}
            `;
        } else {
            select.innerHTML = '<option value="">暂无已完成的解析任务</option>';
        }
    } catch (error) {
        console.error('加载解析任务失败:', error);
        document.getElementById('parseTaskSelect').innerHTML = '<option value="">加载失败</option>';
    }
}

// 加载切片任务列表
async function loadSlicingTasks() {
    try {
        const response = await apiRequest('/api/v1/slicing/tasks');
        const container = document.getElementById('slicingTasksList');
        
        if (response.items && response.items.length > 0) {
            container.innerHTML = response.items.map(task => `
                <div class="border rounded-lg p-4 hover:bg-gray-50 cursor-pointer" onclick="viewSliceDetails('${task.task_id}')">
                    <div class="flex items-center justify-between">
                        <div class="flex items-center space-x-3">
                            <i class="fas fa-file-alt text-blue-600"></i>
                            <div>
                                <p class="text-sm font-medium text-gray-800">${task.filename}</p>
                                <p class="text-xs text-gray-500">${task.strategy} - ${task.chunk_size}字符/块</p>
                            </div>
                        </div>
                        <div class="text-right">
                            <span class="status-badge status-${task.status}">
                                <i class="fas fa-${getSliceStatusIcon(task.status)} mr-1"></i>
                                ${getSliceStatusText(task.status)}
                            </span>
                            <p class="text-xs text-gray-500 mt-1">${task.total_chunks || 0} 块</p>
                        </div>
                    </div>
                    <div class="mt-2">
                        <div class="w-full bg-gray-200 rounded-full h-2">
                            <div class="bg-${getSliceStatusColor(task.status)}-600 h-2 rounded-full" style="width: ${task.progress}%"></div>
                        </div>
                    </div>
                </div>
            `).join('');
        } else {
            container.innerHTML = `
                <div class="text-center py-8 text-gray-500">
                    <i class="fas fa-inbox text-2xl mb-2"></i>
                    <p>暂无切片任务</p>
                </div>
            `;
        }
    } catch (error) {
        console.error('加载切片任务失败:', error);
        document.getElementById('slicingTasksList').innerHTML = `
            <div class="text-center py-8 text-gray-500">
                <i class="fas fa-exclamation-triangle text-2xl mb-2"></i>
                <p>加载失败</p>
            </div>
        `;
    }
}

// 开始切片
async function startSlicing() {
    const parseTaskId = document.getElementById('parseTaskSelect').value;
    const strategy = document.getElementById('sliceStrategy').value;
    const chunkSize = parseInt(document.getElementById('chunkSize').value);
    const overlapSize = parseInt(document.getElementById('overlapSize').value);
    
    if (!parseTaskId) {
        showNotification('请选择解析任务', 'error');
        return;
    }
    
    const btn = document.getElementById('startSlicingBtn');
    btn.disabled = true;
    btn.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i>处理中...';
    
    try {
        const response = await apiRequest('/api/v1/slicing/create', {
            method: 'POST',
            body: JSON.stringify({
                parse_task_id: parseTaskId,
                strategy: strategy,
                chunk_size: chunkSize,
                overlap_size: overlapSize
            })
        });
        
        showNotification('切片任务创建成功', 'success');
        loadSlicingTasks();
        
        // 重置表单
        document.getElementById('parseTaskSelect').value = '';
        
    } catch (error) {
        console.error('创建切片任务失败:', error);
        showNotification('创建切片任务失败', 'error');
    } finally {
        btn.disabled = false;
        btn.innerHTML = '<i class="fas fa-cut mr-2"></i>开始切片';
    }
}

// 查看切片详情
async function viewSliceDetails(taskId) {
    try {
        const response = await apiRequest(`/api/v1/slicing/tasks/${taskId}`);
        currentSliceTask = response;
        
        const modal = document.getElementById('sliceModal');
        const details = document.getElementById('sliceDetails');
        
        details.innerHTML = `
            <div class="grid grid-cols-2 gap-4">
                <div>
                    <label class="block text-sm font-medium text-gray-700">任务ID</label>
                    <p class="text-sm text-gray-800">${response.task_id}</p>
                </div>
                <div>
                    <label class="block text-sm font-medium text-gray-700">文件名</label>
                    <p class="text-sm text-gray-800">${response.filename}</p>
                </div>
                <div>
                    <label class="block text-sm font-medium text-gray-700">切片策略</label>
                    <p class="text-sm text-gray-800">${getStrategyText(response.strategy)}</p>
                </div>
                <div>
                    <label class="block text-sm font-medium text-gray-700">块大小</label>
                    <p class="text-sm text-gray-800">${response.chunk_size} 字符</p>
                </div>
                <div>
                    <label class="block text-sm font-medium text-gray-700">重叠大小</label>
                    <p class="text-sm text-gray-800">${response.overlap_size} 字符</p>
                </div>
                <div>
                    <label class="block text-sm font-medium text-gray-700">状态</label>
                    <span class="status-badge status-${response.status}">
                        <i class="fas fa-${getSliceStatusIcon(response.status)} mr-1"></i>
                        ${getSliceStatusText(response.status)}
                    </span>
                </div>
                <div>
                    <label class="block text-sm font-medium text-gray-700">总块数</label>
                    <p class="text-sm text-gray-800">${response.total_chunks || 0}</p>
                </div>
                <div>
                    <label class="block text-sm font-medium text-gray-700">进度</label>
                    <div class="flex items-center space-x-2">
                        <div class="w-32 bg-gray-200 rounded-full h-2">
                            <div class="bg-${getSliceStatusColor(response.status)}-600 h-2 rounded-full" style="width: ${response.progress}%"></div>
                        </div>
                        <span class="text-sm text-gray-600">${response.progress}%</span>
                    </div>
                </div>
                <div>
                    <label class="block text-sm font-medium text-gray-700">创建时间</label>
                    <p class="text-sm text-gray-800">${formatDate(response.created_at)}</p>
                </div>
                ${response.completed_at ? `
                <div>
                    <label class="block text-sm font-medium text-gray-700">完成时间</label>
                    <p class="text-sm text-gray-800">${formatDate(response.completed_at)}</p>
                </div>
                ` : ''}
            </div>
            
            ${response.status === 'completed' ? `
            <div class="mt-4 pt-4 border-t">
                <div class="flex items-center justify-between mb-4">
                    <h4 class="text-md font-medium text-gray-800">切片块预览</h4>
                    <button onclick="loadSlicePreview('${response.task_id}')" class="text-blue-600 hover:text-blue-800">
                        <i class="fas fa-refresh mr-1"></i>刷新
                    </button>
                </div>
                <div id="sliceChunksPreview" class="space-y-3 max-h-96 overflow-y-auto">
                    <div class="text-center text-gray-500">
                        <i class="fas fa-spinner fa-spin mr-2"></i>加载中...
                    </div>
                </div>
            </div>
            ` : ''}
        `;
        
        modal.classList.remove('hidden');
        
        // 如果任务已完成，加载切片块预览
        if (response.status === 'completed') {
            loadSlicePreview(response.task_id);
        }
        
    } catch (error) {
        console.error('获取切片详情失败:', error);
        showNotification('获取切片详情失败', 'error');
    }
}

// 加载切片块预览
async function loadSlicePreview(taskId) {
    try {
        const response = await apiRequest(`/api/v1/slicing/tasks/${taskId}/chunks`);
        const container = document.getElementById('sliceChunksPreview');
        
        if (response.items && response.items.length > 0) {
            container.innerHTML = response.items.slice(0, 10).map((chunk, index) => `
                <div class="border rounded-lg p-3">
                    <div class="flex items-center justify-between mb-2">
                        <span class="text-sm font-medium text-gray-700">块 ${index + 1}</span>
                        <span class="text-xs text-gray-500">${chunk.chunk_text.length} 字符</span>
                    </div>
                    <p class="text-sm text-gray-600 line-clamp-3">${chunk.chunk_text.substring(0, 200)}...</p>
                    ${chunk.chunk_text.length > 200 ? `
                        <button onclick="showFullChunk(${index})" class="text-blue-600 hover:text-blue-800 text-sm mt-2">
                            查看完整内容
                        </button>
                    ` : ''}
                </div>
            `).join('');
            
            if (response.items.length > 10) {
                container.innerHTML += `
                    <div class="text-center text-gray-500 text-sm">
                        还有 ${response.items.length - 10} 个块未显示
                    </div>
                `;
            }
        } else {
            container.innerHTML = `
                <div class="text-center text-gray-500">
                    <i class="fas fa-inbox mr-2"></i>暂无切片块
                </div>
            `;
        }
    } catch (error) {
        console.error('加载切片块失败:', error);
        document.getElementById('sliceChunksPreview').innerHTML = `
            <div class="text-center text-gray-500">
                <i class="fas fa-exclamation-triangle mr-2"></i>加载失败
            </div>
        `;
    }
}

// 关闭切片详情模态框
function closeSliceModal() {
    document.getElementById('sliceModal').classList.add('hidden');
    currentSliceTask = null;
}

// 更新块大小输入框可见性
function updateChunkSizeVisibility() {
    const strategy = document.getElementById('sliceStrategy').value;
    const chunkSizeInput = document.getElementById('chunkSize');
    
    if (strategy === 'fixed') {
        chunkSizeInput.disabled = false;
        chunkSizeInput.parentElement.style.opacity = '1';
    } else {
        chunkSizeInput.disabled = true;
        chunkSizeInput.parentElement.style.opacity = '0.5';
    }
}

// 切片状态相关函数
function getSliceStatusIcon(status) {
    const icons = {
        'pending': 'clock',
        'processing': 'spinner fa-spin',
        'completed': 'check-circle',
        'failed': 'times-circle'
    };
    return icons[status] || 'question-circle';
}

function getSliceStatusText(status) {
    const texts = {
        'pending': '等待中',
        'processing': '处理中',
        'completed': '完成',
        'failed': '失败'
    };
    return texts[status] || '未知';
}

function getSliceStatusColor(status) {
    const colors = {
        'pending': 'orange',
        'processing': 'blue',
        'completed': 'green',
        'failed': 'red'
    };
    return colors[status] || 'gray';
}

function getStrategyText(strategy) {
    const texts = {
        'semantic': '语义切片',
        'paragraph': '段落切片',
        'fixed': '固定大小切片'
    };
    return texts[strategy] || '未知';
}

// 显示完整块内容
function showFullChunk(index) {
    if (!currentSliceTask || !currentSliceTask.chunks) {
        return;
    }
    
    const chunk = currentSliceTask.chunks[index];
    const content = `
        <div class="space-y-4">
            <div>
                <label class="block text-sm font-medium text-gray-700">块 ${index + 1}</label>
                <p class="text-sm text-gray-600">${chunk.chunk_text.length} 字符</p>
            </div>
            <div>
                <label class="block text-sm font-medium text-gray-700 mb-2">内容</label>
                <div class="bg-gray-50 p-4 rounded-md max-h-96 overflow-y-auto">
                    <pre class="whitespace-pre-wrap text-sm text-gray-800">${chunk.chunk_text}</pre>
                </div>
            </div>
            <div class="grid grid-cols-2 gap-4">
                <div>
                    <label class="block text-sm font-medium text-gray-700">页码</label>
                    <p class="text-sm text-gray-800">${chunk.page_number || 'N/A'}</p>
                </div>
                <div>
                    <label class="block text-sm font-medium text-gray-700">位置</label>
                    <p class="text-sm text-gray-800">${chunk.position || 'N/A'}</p>
                </div>
            </div>
        </div>
    `;
    
    document.getElementById('sliceDetails').innerHTML = content;
}
</script>
{% endblock %}